home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 2
/
Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso
/
Aminet
/
gfx
/
conv
/
Wasp202b.lha
/
wasp
/
src
/
wriffcount.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-12-30
|
12KB
|
591 lines
/* wasp - Copyright 1991 by Steven Reiz
* see COPYING and wasp.c for further info
* wriffcount.c, 4/12/90 - 29/12/90,
* 2/6/91, 23/6/91, 1/7/91 - 10/7/91, 8/12/91
*/
static char *sourcefile=__FILE__;
#include "wasp.h"
#include "wriff.h"
static u_char *xor_tab=NULL;
#ifndef AZTEC_C
/* this function has been rewritten in assembler for the Aztec C
* assembler, see wriffasm.c
*/
void
clear_counts(void)
{
short i;
u_long *p;
long r0, r1, r2, r3, r4, r5, r6, r7;
p=counts; i=NRGB/16-1;
r0=0; r1=r0; r2=r0; r3=r0;
r4=r0; r5=r0; r6=r0; r7=r0;
do {
*p++ =r0; *p++ =r1; *p++ =r2; *p++ =r3;
*p++ =r4; *p++ =r5; *p++ =r6; *p++ =r7;
*p++ =r0; *p++ =r1; *p++ =r2; *p++ =r3;
*p++ =r4; *p++ =r5; *p++ =r6; *p++ =r7;
} while (--i>=0);
}
#endif /* AZTEC_C */
void
fill_xor_tab(void)
{
short i;
u_char *tab;
xor_tab=Malloc(NRGB);
tab=xor_tab+NRGB;
i=NRGB-1;
do {
if ((i&0xf0f)==0 || (i&0xff0)==0 || (i&0x0ff)==0)
*--tab=0;
else
*--tab=1;
} while (--i>=0);
}
void
call1(int row)
{
u_short *pp;
u_long *cp;
short x;
pp=rgb[row];
cp=counts;
x=xsz-1;
do {
++cp[*pp++];
} while (--x>=0);
}
void
calldif(int row)
{
u_short *pp;
u_long *cp;
short x;
short prevcolor, color;
short d, t;
pp=rgb[row];
cp=counts;
x=xsz-1;
prevcolor=0;
do {
color= *pp++;
t=(color-prevcolor)>>8;
if (t<0) d= -t; else d=t;
t=((color&0x00f0)-(prevcolor&0x00f0))>>4;
if (t<0) d-=t; else d+=t;
t=(color&0x000f)-(prevcolor&0x000f);
if (t<0) d-=t; else d+=t;
cp[color]+=d;
prevcolor=color;
} while (--x>=0);
}
void
callfixdif(int row)
{
u_short *pp;
u_long *cp;
short x;
short prevcolor, color;
short r, g, b;
pp=rgb[row];
cp=counts;
x=xsz-1;
prevcolor=0;
do {
color= *pp++;
r=(color-prevcolor)>>8;
if (r<0) r= -r;
g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
if (g<0) g= -g;
b=(color&0x000f)-(prevcolor&0x000f);
if (b<0) b= -b;
if (r>g) {
if (b>r)
cp[color]+=r+g;
else
cp[color]+=b+g;
} else {
if (b>g)
cp[color]+=r+g;
else
cp[color]+=r+b;
}
prevcolor=color;
} while (--x>=0);
}
void
cjump1(int row)
{
u_short *pp;
u_long *cp;
u_char *tab;
short x;
long prevcolor, color;
if (!xor_tab)
fill_xor_tab();
tab=xor_tab;
pp=rgb[row];
cp=counts;
prevcolor= *pp++;
++cp[prevcolor];
x=xsz-2;
do {
color= *pp++;
if (tab[color^prevcolor])
++cp[color];
prevcolor=color;
} while (--x>=0);
}
void
cjump21(int row)
{
u_short *pp;
u_long *cp;
u_char *tab;
short x;
long prevcolor, color, add;
if (!xor_tab)
fill_xor_tab();
tab=xor_tab;
pp=rgb[row];
cp=counts;
add=1;
prevcolor= *pp++;
cp[prevcolor]+=2;
x=xsz-2;
do {
color= *pp++;
if (tab[color^prevcolor])
add=2;
cp[color]+=add;
add>>=1;
prevcolor=color;
} while (--x>=0);
}
void
cjumpdif(int row)
{
u_short *pp;
u_long *cp;
u_char *tab;
short x;
long prevcolor, color, d, t;
if (!xor_tab)
fill_xor_tab();
tab=xor_tab;
pp=rgb[row];
cp=counts;
prevcolor= *pp++;
cp[prevcolor]+=12;
x=xsz-2;
do {
color= *pp++;
if (tab[color^prevcolor]) {
if ((d=(color-prevcolor)>>8)<0)
d= -d;
if ((t=((color&0x00f0)-(prevcolor&0x00f0))>>4)<0)
d-=t;
else
d+=t;
if ((t=(color&0x000f)-(prevcolor&0x000f))<0)
d-=t;
else
d+=t;
cp[color]+=d;
}
prevcolor=color;
} while (--x>=0);
}
void
cjumpdifsh(int row)
{
u_short *pp;
u_long *cp;
short x;
short prevcolor, color;
short d, t;
long add;
pp=rgb[row];
cp=counts;
color= *pp;
add=(color>>8)+((color>>4)&0x0f)+(color&0x0f);
prevcolor=0;
x=xsz-1;
do {
color= *pp++;
t=color^prevcolor;
if (!( (t&0xf0f)==0 || (t&0xff0)==0 || (t&0x0ff)==0 )) {
t=(color-prevcolor)>>8;
if (t<0) d= -t; else d=t;
t=((color&0x00f0)-(prevcolor&0x00f0))>>4;
if (t<0) d-=t; else d+=t;
t=(color&0x000f)-(prevcolor&0x000f);
if (t<0) d-=t; else d+=t;
if (add<d)
add=d;
}
cp[color]+=add;
add>>=1;
prevcolor=color;
} while (--x>=0);
}
void
cjumpfixdif(int row)
{
u_short *pp;
u_long *cp;
short x;
short prevcolor, color;
short r, g, b;
pp=rgb[row];
cp=counts;
prevcolor= *pp++;
r=prevcolor>>8;
g=(prevcolor>>4)&0x0f;
b=prevcolor&0x0f;
if (r>g) {
if (b>r)
cp[prevcolor]+=r+g;
else
cp[prevcolor]+=b+g;
} else {
if (b>g)
cp[prevcolor]+=r+g;
else
cp[prevcolor]+=r+b;
}
x=xsz-2;
do {
color= *pp++;
r=color^prevcolor;
if (!( (r&0xf0f)==0 || (r&0xff0)==0 || (r&0x0ff)==0 )) {
r=(color-prevcolor)>>8;
if (r<0) r= -r;
g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
if (g<0) g= -g;
b=(color&0x000f)-(prevcolor&0x000f);
if (b<0) b= -b;
if (r>g) {
if (b>r)
cp[color]+=r+g;
else
cp[color]+=b+g;
} else {
if (b>g)
cp[color]+=r+g;
else
cp[color]+=r+b;
}
}
prevcolor=color;
} while (--x>=0);
}
void
cjumpfixdifsh(int row)
{
u_short *pp;
u_long *cp;
short x;
short prevcolor, color;
short r, g, b;
long add;
pp=rgb[row];
cp=counts;
prevcolor=0;
color= *pp;
r=color>>8;
g=(color>>4)&0x0f;
b=color&0x0f;
if (r>g) {
if (b>r)
add=r+g;
else
add=b+g;
} else {
if (b>g)
add=r+g;
else
add=r+b;
}
x=xsz-1;
do {
color= *pp++;
r=color^prevcolor;
if (!( (r&0xf0f)==0 || (r&0xff0)==0 || (r&0x0ff)==0 )) {
r=(color-prevcolor)>>8;
if (r<0) r= -r;
g=((color&0x00f0)-(prevcolor&0x00f0))>>4;
if (g<0) g= -g;
b=(color&0x000f)-(prevcolor&0x000f);
if (b<0) b= -b;
if (r>g) {
if (b>r)
add=r+g;
else
add=b+g;
} else {
if (b>g)
add=r+g;
else
add=r+b;
}
}
cp[color]+=add;
add>>=1;
prevcolor=color;
} while (--x>=0);
}
void
chammap(int row)
{
u_short *pp;
u_long *cp;
short x;
long curcolor;
long r, g, b, pr, pg, pb, d1, d2, d3;
pp=rgb[row];
cp=counts;
x=xsz-1;
pb=curcm[0];
pr=pb>>8;
pg=(pb>>4)&0xf;
pb&=0xf;
do {
curcolor= *pp++;
b=curcolor;
r=b>>8;
g=(b>>4)&0xf;
b&=0xf;
if (r==pr) {
if (g==pg) { /* r ok, g ok */
pb=b;
} else {
if (b==pb) { /* r ok, g wrong, b ok */
pg=g;
} else { /* r ok, g wrong, b wrong */
if ((d1=g-pg)<0) d1= -d1;
if ((d2=b-pb)<0) d2= -d2;
if (error[curcolor]<(d1<d2 ? d1 : d2)) {
cp[curcolor]+=error[curcolor];
curcolor=newcol[curcolor];
pb=curcm[curcolor];
pr=pb>>8;
pg=(pb>>4)&0xf;
pb&=0xf;
} else if (d1>=d2) {
cp[curcolor]+=d2;
pg=g;
} else {
cp[curcolor]+=d1;
pb=b;
}
}
}
} else {
if (g==pg) {
if (b==pb) { /* r wrong, g ok, b ok */
pr=r;
} else { /* r wrong, g ok, b wrong */
if ((d1=r-pr)<0) d1= -d1;
if ((d2=b-pb)<0) d2= -d2;
if (error[curcolor]<(d1<d2 ? d1 : d2)) {
cp[curcolor]+=error[curcolor];
curcolor=newcol[curcolor];
pb=curcm[curcolor];
pr=pb>>8;
pg=(pb>>4)&0xf;
pb&=0xf;
} else if (d1>=d2) {
cp[curcolor]+=d2;
pr=r;
} else {
cp[curcolor]+=d1;
pb=b;
}
}
} else {
if (b==pb) { /* r wrong, g wrong, b ok */
if ((d1=r-pr)<0) d1= -d1;
if ((d2=g-pg)<0) d2= -d2;
if (error[curcolor]<(d1<d2 ? d1 : d2)) {
cp[curcolor]+=error[curcolor];
curcolor=newcol[curcolor];
pb=curcm[curcolor];
pr=pb>>8;
pg=(pb>>4)&0xf;
pb&=0xf;
} else if (d1>d2) {
cp[curcolor]+=d2;
pr=r;
} else {
cp[curcolor]+=d1;
pg=g;
}
} else { /* r wrong, g wrong, b wrong */
if ((d1=r-pr)<0) d1= -d1;
if ((d2=g-pg)<0) d2= -d2;
if ((d3=b-pb)<0) d3= -d3;
if (error[curcolor]<(d1>d2 ? (d1>d3 ? d2+d3 : d1+d2) : (d2>d3 ? d1+d3 : d1+d2))) {
cp[curcolor]+=error[curcolor];
curcolor=newcol[curcolor];
pb=curcm[curcolor];
pr=pb>>8;
pg=(pb>>4)&0xf;
pb&=0xf;
} else if (d1>d2 && d1>=d3) {
cp[curcolor]+=d2+d3;
pr=r;
} else if (d2>=d3) {
cp[curcolor]+=d1+d3;
pg=g;
} else {
cp[curcolor]+=d1+d2;
pb=b;
}
}
}
}
} while (--x>=0);
}
void
fill_curcm(short meth)
{
int i;
short c=0;
static short cubic[]={
0x222, 0xe22, 0x2e2, 0x22e,
0x666, 0xa66, 0x6a6, 0x66a,
0x6aa, 0xa6a, 0xaa6, 0xaaa,
0x2ee, 0xe2e, 0xee2, 0xeee
};
for (i=0; i<16; ++i) {
switch (meth) {
case COUNTMETH_HAMMAP_GS:
curcm[i]=c;
c+=0x111;
break;
case COUNTMETH_HAMMAP_CUBIC:
curcm[i]=cubic[i];
break;
}
}
}
int
count_colors(unsigned long thr)
{
short i;
long n;
u_long *p, th;
assert((p=counts)!=NULL1);
i=NRGB/8-1; th=thr;
if (th==0)
n=NRGB;
else if (th==1) {
n=0;
do {
if (*p++) ++n; if (*p++) ++n; if (*p++) ++n; if (*p++) ++n;
if (*p++) ++n; if (*p++) ++n; if (*p++) ++n; if (*p++) ++n;
} while (--i>=0);
} else {
n=0;
do {
if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n;
if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n; if (*p++ >=th) ++n;
} while (--i>=0);
}
return (int)n;
}
void
count_pixels(int firstrow, int lastrow, int moverride)
{
static int sfirstrow= -1, slastrow= -1;
short meth; static short smeth= -1;
int row;
void (*countfunc)(int);
if (counts==NULL1)
counts=Malloc(NRGB*sizeof(u_long));
meth=countmeth;
if (moverride)
meth=COUNTMETH_ALL_1;
if (!inoperation && firstrow==sfirstrow && lastrow==slastrow && meth==smeth)
return;
sfirstrow=firstrow; slastrow=lastrow; smeth=meth;
switch (meth) {
case COUNTMETH_ALL_1 : countfunc=call1; break;
case COUNTMETH_ALL_DIF : countfunc=calldif; break;
case COUNTMETH_ALL_FIXDIF : countfunc=callfixdif; break;
case COUNTMETH_JUMP_1 : countfunc=cjump1; break;
case COUNTMETH_JUMP_21 : countfunc=cjump21; break;
case COUNTMETH_JUMP_DIF : countfunc=cjumpdif; break;
case COUNTMETH_JUMP_DIFSH : countfunc=cjumpdifsh; break;
case COUNTMETH_JUMP_FIXDIF : countfunc=cjumpfixdif; break;
case COUNTMETH_JUMP_FIXDIFSH: countfunc=cjumpfixdifsh; break;
case COUNTMETH_HAMMAP_GS:
case COUNTMETH_HAMMAP_CUBIC:
if (xmode!=HAM)
error0(E0_FATAL, E1_IFF, E2_OPTION, E3_ITMETH);
count_pixels(firstrow, lastrow, 1);
fill_curcm(meth);
fill_newcol_count();
countfunc=chammap;
break;
default:
error0(E0_FATAL, E1_IFF, E2_OPTION, E3_COUNTMETH);
break;
}
clear_counts();
for (row=firstrow; row<=lastrow; ++row) {
countfunc(row);
}
}